AvgPoolFusion

NHWC 输入做 2D 平均池化,再按 [minf, maxf] 做范围裁剪(Clip)。 池化窗口落到填充区时,只对落在有效输入内的元素求平均(分母为有效点数,而非固定 \(k_h \times k_w\))。

对输出位置 \((b, y, x, c)\),令窗口起点 \(y_0 = y \cdot s_h - pad_u\)\(x_0 = x \cdot s_w - pad_l\), 有效窗口为与输入相交的部分,有效点数为 \(R\)

\[\begin{split}\begin{aligned} P &= \frac{1}{R} \sum_{(m,n) \in \mathrm{valid}} I[b,\, y_0 + m,\, x_0 + n,\, c] \\ O &= \max(\mathrm{minf},\, \min(P,\, \mathrm{maxf})) \end{aligned}\end{split}\]

\(R = 0\),则 \(P = 0\) 后再裁剪。

输入:
  • input - 输入数据地址,格式 NHWC

  • params - long long 参数数组,长度至少 14,布局见下

  • core_mask - 核掩码(仅共享存储版本使用)

params 布局:

  • [0] in_w - 输入宽

  • [1] in_h - 输入高

  • [2] win_w - 池化核宽

  • [3] win_h - 池化核高

  • [4] output_w - 输出宽

  • [5] output_h - 输出高

  • [6] batch - batch 大小

  • [7] channel - 通道数

  • [8] stride_w - 水平步长

  • [9] stride_h - 垂直步长

  • [10] pad_l - 左侧填充

  • [11] pad_u - 上侧填充

  • [12] minf - 裁剪下限地址(指针,不是数值本身)

  • [13] maxf - 裁剪上限地址(指针,不是数值本身)

输出:
  • output - 输出数据地址,格式 NHWC

支持平台:

FT78NE MT7004

备注

  • FT78NE 支持 int8、fp32

  • MT7004 支持 fp16、fp32

  • params[12] / params[13] 须传入 minf / maxf 的地址;hp_ 版本指向 float16fp_ / i8_ 版本指向 float / int8_t 对应存储

共享存储版本:

void i8_avg_pooling_s(int8_t *input, int8_t *output, long long *params, int core_mask)
void hp_avg_pooling_s(float16 *input, float16 *output, long long *params, int core_mask)
void fp_avg_pooling_s(float *input, float *output, long long *params, int core_mask)

C调用示例:

 1// MT7004 示例(共享存储多核,DDR 地址)
 2void TestAvgPoolFusionSMCFp32(int core_mask) {
 3    int core_id = get_core_id();
 4    int logic_core_id = GetLogicCoreId(core_mask, core_id);
 5    int core_num = GetCoreNum(core_mask);
 6    float *input = (float *)0x81000000;
 7    float *output = (float *)0x90000000;
 8    float minf = 0.0f;
 9    float maxf = 50.0f;
10    long long params[16];
11    if (logic_core_id == 0) {
12        params[0] = 16;              // in_w
13        params[1] = 16;              // in_h
14        params[2] = 2;               // win_w
15        params[3] = 2;               // win_h
16        params[4] = 8;               // output_w
17        params[5] = 8;               // output_h
18        params[6] = 1;               // batch
19        params[7] = 16;              // channel
20        params[8] = 2;               // stride_w
21        params[9] = 2;               // stride_h
22        params[10] = 0;              // pad_l
23        params[11] = 0;              // pad_u
24        params[12] = (long long)&minf;
25        params[13] = (long long)&maxf;
26    }
27    sys_bar(0, core_num);
28    fp_avg_pooling_s(input, output, params, core_mask);
29}
30
31void main() {
32    int core_mask = 0b1111;
33    TestAvgPoolFusionSMCFp32(core_mask);
34}

私有存储版本:

void i8_avg_pooling_p(int8_t *input, int8_t *output, long long *params)
void hp_avg_pooling_p(float16 *input, float16 *output, long long *params)
void fp_avg_pooling_p(float *input, float *output, long long *params)

C调用示例:

 1// MT7004 示例(私有存储单核,AM 地址)
 2void TestAvgPoolFusionAMFp32(void) {
 3    float *input = (float *)0x10000000;
 4    float *output = (float *)0x10020000;
 5    float minf = 0.0f;
 6    float maxf = 50.0f;
 7    long long params[16];
 8    params[0] = 16;              // in_w
 9    params[1] = 16;              // in_h
10    params[2] = 2;               // win_w
11    params[3] = 2;               // win_h
12    params[4] = 8;               // output_w
13    params[5] = 8;               // output_h
14    params[6] = 1;               // batch
15    params[7] = 16;              // channel
16    params[8] = 2;               // stride_w
17    params[9] = 2;               // stride_h
18    params[10] = 0;              // pad_l
19    params[11] = 0;              // pad_u
20    params[12] = (long long)&minf;
21    params[13] = (long long)&maxf;
22    fp_avg_pooling_p(input, output, params);
23}
24
25void main() {
26    TestAvgPoolFusionAMFp32();
27}